package it.polito.connectedcar.simulation;

import it.polito.appeal.traci.SumoTraciConnection;
import it.polito.appeal.traci.VehicleLifecycleObserver;
import it.polito.appeal.traci.connectedcar.sumo.SUMOTrafficLight;
import it.polito.appeal.traci.connectedcar.sumo.SUMOVehicle;
import it.polito.connectedcar.tcc.TCCMain;
import it.polito.connectedcar.trafficlight.ConnectedTrafficLight;
import it.polito.connectedcar.trafficlight.SumoTrafficLightAdapter;
import it.polito.connectedcar.vehicle.ConnectedVehicle;
import it.polito.connectedcar.vehicle.SUMOVehicleAdapter;

import java.net.Inet4Address;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This is the entry point for the SUO simulation environment and is used to
 * monitor step-by-step simulation. It deals with opening a connection toward
 * the SUMO by using a TRACI connector, and starting the TCC process
 * 
 * @author Nicola Aresta
 * 
 */
public class SimulationManager implements VehicleLifecycleObserver {

	private SumoTraciConnection conn;
	private Map<String, ConnectedVehicle> connectedCars;
	private Map<String, ConnectedTrafficLight> connectedTrafficLights;

	public static void main(String[] args) {

		new SimulationManager();
	}

	public SimulationManager() {

		try {
			conn = new SumoTraciConnection(Inet4Address.getByName("192.168.1.101"), 9001, this);
			connectedTrafficLights = new HashMap<String, ConnectedTrafficLight>();
			connectedCars = new ConcurrentHashMap<String, ConnectedVehicle>();
			conn.addVehicleLifecycleObserver(this);
			for (SUMOTrafficLight tr : conn.getConnectedTrafficLights().values()) {
				connectedTrafficLights.put(tr.getID(),new ConnectedTrafficLight(new SumoTrafficLightAdapter(tr)));
			}

			/* start the TCCMain process */
			new TCCMain(null, conn);

			// the first two steps of this simulation have no vehicles.
			int maximumSteps = 130;
			while (maximumSteps > 0 && !conn.isClosed()) {
				conn.nextSimStep();
				Thread.sleep(600);
				maximumSteps--;
			}
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void vehicleDeparted(SUMOVehicle vehicle) {

		ConnectedVehicle cv;
		try {
			cv = new ConnectedVehicle(new SUMOVehicleAdapter(vehicle));
			this.connectedCars.put(vehicle.getID(), cv);
			cv.onConnect();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void vehicleArrived(SUMOVehicle vehicle) {
		this.connectedCars.get(vehicle.getID()).onDisconnect();
		this.connectedCars.remove(vehicle.getID());

	}

	@Override
	public void vehicleTeleportStarting(SUMOVehicle vehicle) {
		// TODO Auto-generated method stub

	}

	@Override
	public void vehicleTeleportEnding(SUMOVehicle vehicle) {
		// TODO Auto-generated method stub
	}
}
